package com.bean;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.poi.ss.usermodel.Sheet;

import com.utils.ExcelUtils;
import com.utils.KV;

public abstract class GameModel {
	
	/** 白色，都读取 */
	public static final int BOTH_RED = 64;

	/** 黄色，前端读取 */
	public static final int FRONT_YELLOW = 13;

	/** 红色，后端读取 */
	public static final int BACK_WHITE = 10;

	/** 切分字符串 **/
	public static final String CONST_SPIT = "##";

	/** 分隔符 ; **/
	public static final String SPLICE = ";";
	/** 分隔符 @ **/
	public static final String SPLICE1 = "@";
	/** 分隔符 , **/
	public static final String SPLICE2 = ",";
	/** 分隔符 - **/
	public static final String SPLICE3 = "-";
	/** 分隔符 # **/
	public static final String SPLICE4 = "#";
	/** 分隔符 _ **/
	public static final String SPLICE5 = "_";
	/** 分隔符 / **/
	public static final String SPLICE6 = "/";
	
	/** 主键 **/
	public static final String PRIMARY_KEY = "id";
	
	/**常量 无内容**/
	public static final String constNull = "";
	/**常量 !**/
	public static final String const1 = "!";
	/**常量 ~**/
	public static final String const2 = "~";
	
	public GameModel() {
	}
	
	
	/**加载之后初始化**/
	public abstract void init();

	/**
	 * 复合索引 填法: String[0]=id##name <br>
	 * String[1]=id##level<br>
	 * 这样代表创建了2个符合索引 <br>
	 * 也可以单索引 填法 String[0]=name;
	 * 
	 * @return
	 */
	public String[] getComplexIndex() {
		return null;
	}
	
	/**
	 * 是否缓存hashset格式
	 * 
	 * @return
	 */
	public boolean isHash() {
		return false;
	}
	
	/** 获取排序方式 **/
	public KV<String, Comparator<GameModel>>[] getSort() {
		return null;
	}
	
	/**
	 * 设置对象的值
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public void setValue(String key, String value, int line) throws Exception {
		try {
			Field field = getClass().getField(key);
			field.setAccessible(true);
			Class<?> class1 = field.getType();
			if (class1 == Integer.TYPE) {
				field.setInt(this, Integer.parseInt(value));
			} else if (class1 == Integer.class) {
				field.set(this, new Integer(value));
			} else if (class1 == Long.TYPE) {
				field.setLong(this, Long.parseLong(value));
			} else if (class1 == Long.class) {
				field.set(this, Long.valueOf(value));
			} else if (class1 == Boolean.TYPE)
				field.setBoolean(this, Boolean.getBoolean(value));
			else if (class1 == Boolean.class)
				field.set(this, Boolean.valueOf(value));
			else if (class1 == Float.TYPE)
				field.setFloat(this, Float.valueOf(value).floatValue());
			else if (class1 == Float.class)
				field.set(this, Float.valueOf(value));
			else if (class1 == Double.TYPE)
				field.setDouble(this, Double.valueOf(value).doubleValue());
			else if (class1 == Double.class)
				field.set(this, Double.valueOf(value));
			else if (class1 == (java.lang.String.class)) {
				field.set(this, value);
			} else if (class1 == Date.class) {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
				field.set(this, sdf.parse(value));
			}
			field.setAccessible(false);
		} catch (Exception e) {
			throw new RuntimeException("属性" + key + "值" + value, e);
		}
	}
	
	/**
	 * 初始化model
	 * 
	 * @param sheet
	 * @param GameModelClass
	 * @param arraylist
	 */
	public static final <T extends GameModel> void initModels(Sheet sheet, Class<T> GameModelClass, List<T> arraylist,
			Map<String, Map<String, List<GameModel>>> listMap, Map<String, Map<String, Set<GameModel>>> setMap) {
		try {
			int cellLenth = sheet.getRow(1).getLastCellNum();
			int rowLenth = sheet.getLastRowNum();
			Map<Integer, Integer> colorMap = ExcelUtils.getSheetColor(sheet);
			Map<Integer, String> titleMap = ExcelUtils.getRowValues(sheet, 1, cellLenth, null);
			Map<Integer, String> cellTypeMap = ExcelUtils.getRowValues(sheet, 2, cellLenth, null);
			for (int i = 3; i <= rowLenth; i++) {
				Map<Integer, String> valuesMap = ExcelUtils.getRowValues(sheet, i, cellLenth, cellTypeMap);
				if (valuesMap.get(0) == null || valuesMap.get(0).isEmpty()) {
					continue;
				}
				T gameModel = null;
				try {
					gameModel = GameModelClass.newInstance();
				} catch (InstantiationException e) {
					e.printStackTrace();
					return;
				} catch (IllegalAccessException e) {
					e.printStackTrace();
					return;
				}

				// 检测excel错误
//				for (int index : colorMap.keySet()) {
//					int color = colorMap.get(index);
//					if (color != BOTH_RED && color != BACK_WHITE)
//						continue;
//					String title = titleMap.get(index);
//					if (title == null || title.equals(""))
//						continue;
//					String values = valuesMap.get(index);
//					if (values != null && !values.equals("")) {
//						values = values.replaceAll(" ", "");
//						values = values.replaceAll("，", ",");
//						values = values.replaceAll("：", ":");
//						title = title.trim();
//						values = values.trim();
//					}
//					gameModel.checkExcel(title, values, excelCheck.get(index), i, cellTypeMap.get(index));
//				}
				// excel转换对象
				for (int index : colorMap.keySet()) {
					int color = colorMap.get(index);
					if (color != BOTH_RED && color != BACK_WHITE)
						continue;
					String title = titleMap.get(index);
					if (title == null || title.equals(""))
						continue;
					String values = valuesMap.get(index);
					if (values != null && !values.equals("")) {
						values = values.replaceAll(" ", "");
						values = values.replaceAll("：", ":");
						values = values.replaceAll("；", ";");
						values = values.replaceAll("，", ",");
						title = title.trim();
						values = values.trim();
						gameModel.setValue(title, values, rowLenth);
					}
				}
				arraylist.add(gameModel);
				// 创建索引
				String[] indexs = gameModel.getComplexIndex();
				if (indexs == null)
					continue;
				for (String index : indexs) {
					String[] temps = index.split(CONST_SPIT);
					StringBuilder sb = new StringBuilder();
					for (String temp : temps) {
						sb.append(GameModelClass.getField(temp).get(gameModel));
						sb.append(CONST_SPIT);
					}
					String indexValues = sb.toString();

					Map<String, List<GameModel>> mapList = listMap.get(index);
					if (mapList == null) {
						mapList = new HashMap<String, List<GameModel>>();
						listMap.put(index, mapList);
					}
					List<GameModel> list = mapList.get(indexValues);
					if (list == null) {
						list = new ArrayList<GameModel>();
						mapList.put(indexValues, list);
					}
					list.add(gameModel);

					if (setMap == null)
						continue;
					Map<String, Set<GameModel>> mapSet = setMap.get(index);
					if (mapSet == null) {
						mapSet = new HashMap<String, Set<GameModel>>();
						setMap.put(index, mapSet);
					}
					Set<GameModel> set = mapSet.get(indexValues);
					if (set == null) {
						set = new HashSet<GameModel>();
						mapSet.put(indexValues, set);
					}
					set.add(gameModel);

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("解析配置表错误,文件名:" + GameModelClass.getName(), e);
		}
	}
	
	
	/**
	 * list 转换成map
	 * 
	 * @param list
	 * @param map
	 * @param key
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static final <T extends GameModel> void listToMap(List<T> list, Map map, String key) {
		try {
			for (T config : list) {
				Field field = config.getClass().getField(key);
				Object obj = field.get(config);
				map.put(obj, config);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 复制对象
	 * 
	 */
	public Object clone() {
		GameModel gameModel = null;
		try {
			gameModel = (GameModel) super.clone();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return gameModel;
	}
	
	public abstract String getFileName();
}

